package com.ruyuan.seckilling.activity.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruyuan.dependency.product.api.ProductApi;
import com.ruyuan.dependency.product.vo.SkuIdAndStock;
import com.ruyuan.seckilling.activity.constant.ActivityStatusVal;
import com.ruyuan.seckilling.activity.entity.Activity;
import com.ruyuan.seckilling.activity.entity.ActivitySkuRef;
import com.ruyuan.seckilling.activity.request.ActivityModifyRequest;
import com.ruyuan.seckilling.activity.request.ActivityQueryPageRequest;
import com.ruyuan.seckilling.activity.request.ActivitySaveRequest;
import com.ruyuan.seckilling.activity.service.ActivityService;
import com.ruyuan.seckilling.activity.service.ActivitySkuRefService;
import com.ruyuan.seckilling.common.MapResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhonghuashishan
 */
@Slf4j
@RestController
@RequestMapping("/activity")
public class ActivityController {

    @Autowired
    private ActivityService activityService;

    @Autowired
    private ActivitySkuRefService activitySkuRefService;

    @Autowired
    private ProductApi productApi;

    /**
     * 后台查询秒杀活动
     */
    @GetMapping("/queryPage")
    public MapResult queryPage(@RequestBody ActivityQueryPageRequest request) {
        String validateResult = request.validateParams();
        if (Objects.nonNull(validateResult)) {
            return MapResult.errorResult().setInfo(validateResult);
        }

        IPage<Activity> page = activityService.queryPage(request);
        List<Activity> activities = page.getRecords();
        if (CollectionUtils.isEmpty(activities)) {
            return MapResult.successResult().set("totalPage", 1).set("totalCount", 0)
                    .set("dataList", Collections.emptyList());
        }

        List<Long> activityIds = activities.stream().map(Activity::getId).collect(Collectors.toList());
        List<ActivitySkuRef> activitySkuRefs = activitySkuRefService.queryByActivityIds(activityIds);
        Map<Long, List<ActivitySkuRef>> activityIdSkuRefMap = activitySkuRefs.stream()
                .collect(Collectors.groupingBy(ActivitySkuRef::getActivityId));

        List<Object> dataList = new ArrayList<>();
        for (Activity activity : activities) {
            Map<String, Object> data = new LinkedHashMap<>();
            data.put("activityId", activity.getId());
            data.put("activityName", activity.getActivityName());
            data.put("showTime", activity.getShowTime());
            data.put("startTime", activity.getStartTime());
            data.put("endTime", activity.getEndTime());
            data.put("status", activity.getStatus());
            data.put("pageReady", activity.getPageReady());
            data.put("auditComment", activity.getAuditComment());
            data.put("creatTime", activity.getCreateTime());
            data.put("updateTime", activity.getUpdateTime());
            data.put("seckillingSkuCount", Optional.ofNullable(activityIdSkuRefMap)
                    .map(e -> e.get(activity.getId())).map(List::size).orElse(0));
            dataList.add(data);
        }
        return MapResult.successResult().set("totalPage", page.getPages()).set("totalCount", page.getTotal())
                .set("dataList", dataList);
    }

    /**
     * 添加秒杀活动
     */
    @PostMapping("/save")
    public MapResult save(@RequestBody ActivitySaveRequest request) {
        String validateResult = request.validateParams();
        if (Objects.nonNull(validateResult)) {
            return MapResult.errorResult().setInfo(validateResult);
        }

        Activity.ActivityBuilder builder = Activity.builder();
        // 来自参数的字段值
        builder.activityName(request.getActivityName())
                .showTime(request.getShowTime())
                .startTime(request.getStartTime())
                .endTime(request.getEndTime());
        // 初始化的字段值
        builder.status(ActivityStatusVal.NEW_CREATE.getCode());
        builder.pageReady(Boolean.FALSE);
        builder.auditComment(null);
        Activity activity = builder.build();
        activityService.save(activity);
        log.info("保存活动，activityId={}，activity={}", activity.getId(), JSON.toJSONString(activity));
        return MapResult.successResult().set("id", activity.getId());
    }

    /**
     * 修改秒杀活动
     */
    @PutMapping("/modify")
    public MapResult modify(@RequestBody ActivityModifyRequest request) {
        String validateResult = request.validateParams();
        if (Objects.nonNull(validateResult)) {
            return MapResult.errorResult().setInfo(validateResult);
        }
        Activity activity = activityService.queryById(request.getActivityId());
        if (Objects.isNull(activity)) {
            return MapResult.errorResult().setInfo("活动不存在");
        }
        if (activity.getStatus() >= ActivityStatusVal.AUDIT_PASS.getCode()) {
            return MapResult.errorResult().setInfo("该活动在当前状态下不允许修改");
        }
        activityService.modify(request);
        return MapResult.successResult();
    }

    /**
     * 删除秒杀活动
     */
    @DeleteMapping("/remove/{id}")
    public MapResult remove(@PathVariable("id") Long id) {
        Activity activity = activityService.queryById(id);

        // 页面渲染中状态之前的活动都可以随便删除，之后的的状态都不能随便删除
        if (activity.getStatus() >= ActivityStatusVal.PAGE_RENDERING.getCode()) {
            return MapResult.errorResult().setInfo("活动在当前状态下不可以删除");
        }

        List<ActivitySkuRef> activitySkuRefs = activitySkuRefService.queryByActivityId(id);

        // 调用商品服务释放商品库存
        List<SkuIdAndStock> skuIdAndStockList = new ArrayList<>();
        for (ActivitySkuRef activitySkuRef : activitySkuRefs) {
            skuIdAndStockList.add(new SkuIdAndStock(activitySkuRef.getSkuId(), activitySkuRef.getSeckillingStock()));
        }
        productApi.batchReleaseStock(skuIdAndStockList);
        log.info("释放秒杀活动关联的秒杀商品的库存");

        // 删除秒杀商品
        List<Long> activitySkuRefIds = activitySkuRefs.stream().map(ActivitySkuRef::getId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(activitySkuRefIds)) {
            activitySkuRefService.batchRemove(activitySkuRefIds);
        }
        log.info("删除秒杀活动和秒杀商品关联关系");

        // 删除秒杀活动
        activityService.remove(id);
        log.info("删除秒杀活动");

        return MapResult.successResult();
    }

    /**
     * 关闭秒杀活动
     * 对于已经开始渲染页面的秒杀活动是不可以删除的，如果确实需要删除可以"关闭"秒杀活动
     * 关闭之后该秒杀活动不可用了，用户也看不到，但是后面的流程还是会走正常的逻辑，等时间到了自动
     */
    @PutMapping("/close/{id}")
    public MapResult close(@PathVariable("id") Long id) {
        List<ActivitySkuRef> activitySkuRefs = activitySkuRefService.queryByActivityId(id);

        // 调用商品服务释放商品库存
        List<SkuIdAndStock> skuIdAndStockList = new ArrayList<>();
        for (ActivitySkuRef activitySkuRef : activitySkuRefs) {
            skuIdAndStockList.add(new SkuIdAndStock(activitySkuRef.getSkuId(), activitySkuRef.getSeckillingStock()));
        }
        productApi.batchReleaseStock(skuIdAndStockList);
        log.info("释放秒杀活动关联的秒杀商品的库存");

        activityService.updataStatus(id, null, ActivityStatusVal.ACTIVITY_CLOSED.getCode());
        log.info("修改秒杀活动的状态为已关闭");

        return MapResult.successResult();
    }

    /**
     * 提交审核秒杀活动
     */
    @PutMapping("/submit/{id}")
    public MapResult submit(@PathVariable("id") Long id) {
        activityService.updataStatus(id,
                ActivityStatusVal.NEW_CREATE.getCode(),
                ActivityStatusVal.AUDIT_PENDING.getCode());
        return MapResult.successResult();
    }


    /**
     * 提交审核秒杀活动
     */
    @PutMapping("/audit/{id}")
    public MapResult audit(@PathVariable("id") Long id, Boolean result) {
        if (result) {
            // 审核通过
            activityService.updataStatus(id,
                    ActivityStatusVal.AUDIT_PENDING.getCode(),
                    ActivityStatusVal.AUDIT_PASS.getCode());
        } else {
            // 审核不通过
            activityService.updataStatus(id,
                    ActivityStatusVal.AUDIT_PENDING.getCode(),
                    ActivityStatusVal.AUDIT_NOT_PASS.getCode());
        }
        return MapResult.successResult();
    }
}
